package com.yunkeji.config.timer;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import com.baomidou.lock.executor.RedissonLockExecutor;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yunkeji.api.user.mapper.ApiAppUserMapper;
import com.yunkeji.common.constant.CacheConstants;
import com.yunkeji.common.enums.app.AppUserStatus;
import com.yunkeji.common.utils.redis.RedisUtils;
import com.yunkeji.dao.domain.AppUser;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Date;
import java.util.List;

/**
 * 账号删除定时器-每天零点删除当天需要被删除的账号,发进去redis队列
 *
 * @author 老张
 */
@Component
@EnableScheduling
@Slf4j
@AllArgsConstructor
public class DelAccountTimer {

    private final ApiAppUserMapper apiAppUserMapper;
    private final LockTemplate lockTemplate;

    /**
     * 测试服五分钟检测一次,
     *
     * @author 老张
     */
    @Scheduled(fixedRate = 5 * 60 * 1000)
    @Profile("test")
    public void delAccountTest() {
        log.info("账号删除检测-test");
        delTodayAccount();
    }

    //    @Scheduled(fixedRate = 5000)
//    @Profile("dev")
    public void delAccountDev() {
        delTodayAccount();
    }

    @Scheduled(cron = "0 0 0 * * ?")
    @Profile("prod")
    public void delAccountProd() {
        log.info("账号删除检测-prod");
        delTodayAccount();
    }

    /** 删除当天的账号 */
    private void delTodayAccount() {
        log.info("账号删除检测....");
        final LockInfo lockInfo =
                lockTemplate.lock(
                        CacheConstants.LOCK_DEL_ACCOUNT_TIMER,
                        30000L,
                        5000L,
                        RedissonLockExecutor.class);
        if (null == lockInfo) {
            throw new RuntimeException("业务处理中,请稍后再试");
        }
        try {
            Date currentDate = new Date();
            List<AppUser> appUsers =
                    apiAppUserMapper.selectList(
                            Wrappers.lambdaQuery(AppUser.class)
                                    .select(AppUser::getId, AppUser::getAccountDelDate)
                                    .ge(
                                            AppUser::getAccountDelDate,
                                            DateUtil.beginOfDay(currentDate))
                                    .le(AppUser::getAccountDelDate, DateUtil.endOfDay(currentDate))
                                    .eq(AppUser::getStatus, AppUserStatus.等待删除.getCode()));
            log.info("账号删除检测....{}", appUsers.size());
            appUsers.forEach(
                    item -> {
                        Object cacheObject =
                                RedisUtils.getCacheObject(
                                        CacheConstants.DEL_ACCOUNT + item.getId());
                        if (cacheObject == null) {
                            long l =
                                    DateUtil.between(
                                            currentDate, item.getAccountDelDate(), DateUnit.SECOND);
                            RedisUtils.setCacheObject(
                                    CacheConstants.DEL_ACCOUNT + item.getId(),
                                    item.getId(),
                                    Duration.ofSeconds(l));
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            lockTemplate.releaseLock(lockInfo);
        }
    }
}
